package com.alibaba.csp.sentinel.dashboard.task.nacos;

import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.controller.v2.FlowControllerV2;
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

@Component("SyncRuleNacosTask")
public class SyncRuleNacosTask {

    private final Logger logger = LoggerFactory.getLogger(FlowControllerV2.class);

    @Autowired
    private AppManagement appManagement;

    @Autowired
    private SentinelApiClient sentinelApiClient;

    @Autowired
    @Qualifier("flowRuleNacosProvider")
    private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;

    @Scheduled(cron="0/10 * * * * ? ")
    public void syncFlowRules(){
        List<String> appNames = appManagement.getAppNames();
        appNames.stream().forEach(app -> {
            // 查询规则
            try{
                List<FlowRuleEntity> rules = ruleProvider.getRules(app);
                if(rules == null || rules.isEmpty()) {
                    return;
                }
                // 推送至每个存活的实例
                appManagement.getDetailApp(app).getMachines()
                        .stream()
                        .filter(MachineInfo::isHealthy).forEach(p -> {
                    sentinelApiClient.setFlowRuleOfMachine(app, p.getIp(), p.getPort(), rules);
                });
            }catch (Throwable throwable) {
                logger.error("Task: failed to sync flow rule", throwable);
            }
        });

    }
}
